/**
 * AudioCacheUtil.js
 * import AudioCacheUtil from '@/utils/AudioCacheUtil.js';
 *
 * // 第一次点击 → 播放
 * AudioCacheUtil.play('hello', 'uk');
 *
 * // 第二次点击同样参数 → 停止播放
 * AudioCacheUtil.play('hello', 'uk');
 *
 * // 点击不同单词 → 切换播放
 * AudioCacheUtil.play('world', 'uk');
 *
 * // 手动停止
 * AudioCacheUtil.stop();
 */
import { getTts } from '@/api/wordHelper'

class AudioCacheUtil {
  static instance = null

  constructor() {
    this.cache = new Map() // LRU 缓存
    this.maxCacheSize = 1000
    this.playCounter = 0

    this.currentAudio = null
    this.currentKey = null

    this.isPlaying = false
  }

  static getInstance() {
    if (!AudioCacheUtil.instance) {
      AudioCacheUtil.instance = new AudioCacheUtil()
    }
    return AudioCacheUtil.instance
  }

  /**
   * 之前只缓存单词 现在关闭 都缓存
   * @param text
   * @returns {boolean}
   */
  isWord(text) {
    // 支持 a-z, A-Z, 可以带撇号和连字符
    // return /^[A-Za-z]+(['-][A-Za-z]+)*$/.test(text)
    return true
  }

  genKey(text, lan) {
    return `${lan}::${text.toLowerCase()}`
  }

  evictIfNeeded() {
    while (this.cache.size >= this.maxCacheSize) {
      let oldestKey = null
      let oldestUsed = Infinity

      for (const [key, value] of this.cache.entries()) {
        if (value.used < oldestUsed) {
          oldestUsed = value.used
          oldestKey = key
        }
      }

      if (oldestKey) {
        URL.revokeObjectURL(this.cache.get(oldestKey).url)
        this.cache.delete(oldestKey)
      } else {
        break
      }
    }
  }

  async fetchAudio(text, lan) {
    const res = await getTts({ text, lan })
    if (res.status !== 200) throw new Error('音频请求失败')
    const blob = res.data
    return URL.createObjectURL(blob)
  }

  stop() {
    if (this.currentAudio) {
      try {
        this.currentAudio.pause()
      } catch (err) {
      }
      this.currentAudio.currentTime = 0
      this.currentAudio = null
      this.currentKey = null
      this.isPlaying = false
    }
  }

  async play(text, lan, speed = 1.0) {
    const key = this.genKey(text, lan)

    // 如果同一单词正在播放 → 停止播放
    if (this.currentKey === key && this.currentAudio) {
      this.stop()
      return
    }

    // 防止快速切换重复播放
    if (this.isPlaying) {
      this.stop()
    }

    let audioUrl
    if (this.cache.has(key)) {
      const item = this.cache.get(key)
      item.used = ++this.playCounter
      audioUrl = item.url
    } else {
      audioUrl = await this.fetchAudio(text, lan)
      if (this.isWord(text)) {
        this.cache.set(key, { url: audioUrl, used: ++this.playCounter })
        this.evictIfNeeded()
      }
    }

    const audio = new Audio(audioUrl)
    audio.playbackRate = speed // ✅ 设置播放速度
    this.currentAudio = audio
    this.currentKey = key
    this.isPlaying = true

    audio.play().catch(err => {
      if (err.name !== 'AbortError') {
        console.error('音频播放失败', err)
      }
    })

    audio.addEventListener('ended', () => this.stop())
    audio.addEventListener('error', () => this.stop())
  }
}

export default AudioCacheUtil.getInstance()
